package nina.yiyou.salary.input.info

import luj.groovy.excel.api.LugExcel
import luj.groovy.excel.api.table.Table
import luj.groovy.excel.api.table.body.Row
import luj.groovy.excel.api.table.header.Header
import luj.groovy.excel.api.table.header.HeaderField
import nina.yiyou.salary.input.util.ExcelReadOpener
import nina.yiyou.salary.input.util.IdMapMaker
import nina.yiyou.salary.process.global.GlobalResultMaker
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.ss.usermodel.Workbook

import java.util.stream.Collectors

/**
 * 读取社保表
 */
class InsuranceExcelV2Reader {

  InsuranceExcelV2Reader(String excelPath, Map<String, Object> basicMap, GlobalResultMaker.Result globalCfg) {
    _excelPath = excelPath
    _basicMap = basicMap
    _globalCfg = globalCfg
  }

  Map read() {
    GlobalResultMaker.Insurance insuranceCol = _globalCfg.insuranceColumn()
    List colCfg = makeColumnConfig(insuranceCol)

    Workbook workbook = new ExcelReadOpener(_excelPath).openXls()
    List<Map> lines = readLines(workbook.getSheetAt(0), colCfg)
    workbook.close()

    Map idMap = new IdMapMaker(_basicMap).make()
    String idKey = colCfg[1][1]

    return lines.collect { [it, it[idKey]] }
        .findAll { idMap.containsKey(it[1]) }
        .collectEntries { [idMap[it[1]], it[0]] }
  }

  private List makeColumnConfig(GlobalResultMaker.Insurance col) {
    return [
        ['姓名', '姓名', String],
        ['证件号码', '身份证号', String],
        [col.total(), '合计', double],
        [col.pension(), '养老', double],
        [col.unemploy(), '失业', double],
        [col.medical(), '医疗', double],
    ]
  }

  private List<Map> readLines(Sheet sheet, List colCfg) {
    Table table = LugExcel.table(sheet).header {
      startCell('A7')
      rowSize(2)
    }.build()

    return table.body.rows.stream()
        .map { toLineMap(it, table.header, colCfg) }
        .collect(Collectors.toList())
  }

  private Map toLineMap(Row row, Header header, List colCfg) {
    def toEntry = { String path, String resultKey, Class resultType ->
      HeaderField field = header.getField(path)
      assert header.getField(path)

      Object value = getValue(row.getFieldValue(field), resultType)
      return [resultKey, value]
    }
    return colCfg.collectEntries(toEntry)
  }

  private Object getValue(Object raw, Class type) {
    if (type == double) {
      return Double.valueOf(raw as String)
    }
    return raw
  }

  private final String _excelPath

  private final Map<String, Object> _basicMap
  private final GlobalResultMaker.Result _globalCfg
}
